/*
 *  Copyright (C) 2011 JiangHongTiao <jjurco.sk_gmail.com>
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package sk.lieskove.jianghongtiao.websearch.api.google.search;

import org.json.JSONObject;
import sk.lieskove.jianghongtiao.common.exceptions.HTTPResponseException;

import java.util.Map;

/**
 *
 * @author xjuraj
 */
public interface GoogleWebSearch {

    /**
     * make search
     * @return JSON object returned by search query
     */
    public JSONObject search();

    /**
     * add web search params. Param API version number (v=1.0) is here by default
     * and cannot be removed. When you put param with same name more than onece,
     * the last one will be used.
     * @param param web search param name. All values will be URL-escaped. Don't do it again!
     Web search params name should be:
<ul>
  <li>
    <b>Name: </b><underline>v</underline><br>
    <b>Desc: </b>This argument supplies protocol version number. The only valid value at
    this point in time is 1.0.<br>
    <b>Example: </b><i>v=1.0</i>
  </li>
  <li>
    <b>Name: </b><underline>q</underline><br>
    <b>Desc: </b>This argument supplies the query, or search expression, that is passed
    into the searcher.The value specified for the q parameter must be URL-escaped.<br>
    <b>Example: </b><i>q=Paris%20Hilton</i>
  </li>
  <li>
    <b>Name: </b><underline>userip</underline>?<br>
    <b>Desc: </b>This argument supplies the IP address of the end-user on whose behalf
    the request is being made. Requests that include it are less likely to be mistaken
    for abuse. In choosing to utilize this parameter, please be sure that you're
    in compliance with any local laws, including any laws relating to disclosure
    of personal information being sent.<br>
    <b>Example: </b><i>userip=192.168.0.1</i>
  </li>
  <li>
    <b>Name: </b><underline>rsz</underline>?<br>
    <b>Desc: </b>This optional argument supplies the number of results that the application
    would like to recieve. Values can be any integer between 1 and 8. Alternately,
    a value of small indicates a small result set size or 4 results. A value of
    large indicates a large result set or 8 results. Finally, for filter Custom
    Search Engines, a value of filtered_cse will return 10 results. If this argument
    is not supplied, a value of small is assumed.<br>
    <b>Example: </b><i>rsz=4</i>
  </li>
  <li>
    <b>Name: </b><underline>hl</underline>?<br>
    <b>Desc: </b>This optional argument supplies the host language of the application
    making the request. If this argument is not present then the system will choose
    a value based on the value of the Accept-Language http header. If this header
    is not present, a value of en is assumed.<br>
    <b>Example: </b><i>hl=fr</i>
  </li>
  <li>
    <b>Name: </b><underline>key</underline>?<br>
    <b>Desc: </b>This optional argument supplies the application's key. If specified, it
    must be a valid key associated with your site which is validated against the
    passed referer header. The advantage of supplying a key is so that we can identify
    and contact you should something go wrong with your application. Without a key,
    we will still take the same appropriate measures on our side, but we will not
    be able to contact you. It is definitely best for you to pass a key.<br>
    <b>Example: </b><i>key=your-key</i>
  </li>
  <li>
    <b>Name: </b><underline>start</underline>?<br>
    <b>Desc: </b>This optional argument supplies the start index of the first search result.
    Each successful response contains a cursor object (see below) which includes an
    array of pages. The start property for a page may be used as a valid value for
    this argument. For reference, a sample cursor object is shown below:
<code>
"cursor": {
  "pages": [
    { "start": "0", "label": 1 },
    { "start": "4", "label": 2 },
    { "start": "8", "label": 3 },
    { "start": "12","label": 4 } ],
  "estimatedResultCount": "48758",
  "currentPageIndex": 0,
  "moreResultsUrl": "http://www.google.com/search..."
}</code><br>
    <b>Example: </b><i>start=4</i>
  </li>
  <li>
    <b>Name: </b><underline>callback</underline>?<br>
    <b>Desc: </b>This optional argument alters the standard response format. When supplied,
    instead of producing a simple JSON encoded object, the system produces a Javascript
    function call response where the value of callback specifies the name of the function
    called in the response.
<code>
callbackFunction(
  {"responseData" : {
      "results" : [],
      "cursor" : {}
    },
    "responseDetails" : null | string-on-error,
    "responseStatus" : 200 | error-code
});</code><br>
    <b>Example: </b><i>callback=foo</i>
  </li>
  <li>
    <b>Name: </b><underline>context</underline>?<br>
    <b>Desc: </b>This optional argument is related to the context argument. When both are
    supplied, the value of context alters the normal response format associated
    with callback. The new format is:
<code>
callbackFunction(
  contextValue,    // the context arg value
  responseObject,  // the collection of results and cursor
  responseStatus,  // 200 on success, non-200 on failure
  errorDetails)    // error string for non-200 response</code><br>
    <b>Example: </b><i>context=bar</i>
  </li>
  <li>
    <b>Name: </b><underline>cx</underline>?<br>
    <b>Desc: </b>This optional argument supplies the unique id for the Custom Search Engine
    that should be used for this request.<br>
    <b>Example: </b><i>cx=000455696194071821846:reviews</i>
  </li>
  <li>
    <b>Name: </b><underline>cref</underline>?<br>
    <b>Desc: </b>This optional argument supplies the url of a linked Custom Search Engine
    specification that should be used to satisfy this request.<br>
    <b>Example: </b><i>cref=http%3A%2F%2Fwww.google.com%2Fcse%2Fsamples%2Fvegetarian.xml</i>
  </li>
  <li>
    <b>Name: </b><underline>safe</underline>?<br>
    <b>Desc: </b>This optional argument supplies the search safety level which may be one of:<br>
    * safe=active - enables the highest level of safe search filtering<br>
    * safe=moderate - enables moderate safe search filtering (default)<br>
    * safe=off - disables safe search filtering<br>
  </li>
  <li>
    <b>Name: </b><underline>lr</underline>?<br>
    <b>Desc: </b>This optional argument allows the caller to restrict the search to documents
    written in a particular language. This list contains the permissible set of values.<br>
    <b>Example: </b><i>lr=lang_ja</i>
  </li>
  <li>
    <b>Name: </b><underline>filter</underline>?<br>
    <b>Desc: </b>This optional argument controls turning on or off the duplicate content filter:<br>
    * filter=0 - Turns off the duplicate content filter<br>
    * filter=1 - Turns on the duplicate content filter (default)<br>
    <b>Example: </b><i></i>
  </li>
  <li>
    <b>Name: </b><underline>gl</underline>?<br>
    <b>Desc: </b>This optional argument allows the caller to tailor the results to a specific
    country. The value should be a valid country code. If this argument is not present,
    then the system will use a value based on the domain used to load the API
    (e.g. http://www.google.com/jsapi). If the API loader was not used, a value
    of "us" is assumed. <br>
    <b>Example: </b><i>uk, de, etc.</i>
  </li>
</ul>
     * Google Api Doc.
     * http://code.google.com/intl/cs/apis/ajaxsearch/documentation/reference.html#_intro_fonje
     * http://www.google.com/cse/docs/resultsxml.html#cxsp
     * @param value param value
     * @return actual list of params
     */
    public Map<String, String> addWSParam(String param, String value);

    /**
     * remove added param with value. Param 'v' cannot be removed
     * @param param name of param to remove
     * @return map with actual params and values
     */
    public Map<String, String> removeWSParam(String param);

    /**
     * get list of stored params and values
     * @return list of params and values
     */
    public Map<String, String> getListOfParams();

    /**
     * make search with specified number of results
     * maximal number of search results is limited by google to <b>64</b>
     * @param resultCount number of search results
     * @return Google response object
     */
    public GWSResponse search(Integer resultCount) throws HTTPResponseException;

    /**
     * google API key for the application. Key can be generated on page: http://code.google.com/apis/loader/signup.html
     * @param key google API key
     * @return actual instance of GoogleWebSearch
     */
    public GoogleWebSearch withKey(String key);

    /**
     * set language for the search
     * @param lang localized search specified by language
     * @return actual instance of GoogleWebSearch
     */
    public GoogleWebSearch withLanguage(GWSLanguage lang);

    /**
     * set query for the search
     * @param query search query
     * @return actual instance of GoogleWebSearch
     */
    public GoogleWebSearch withQuery(String query);

}
